"""
股票数据分析系统 - 工具函数集
包含数据验证、清洗、转换等辅助功能
"""

import pandas as pd
import numpy as np
import logging
import os
import json
from datetime import datetime
from config import (
    REQUIRED_COLUMNS,
    MAX_PRICE_CHANGE,
    MISSING_DATA_HANDLING,
    LOG_LEVEL
)

# 设置日志
logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)

def validate_stock_data(df):
    """
    验证股票数据完整性
    :param df: 输入的DataFrame
    :return: 验证通过的DataFrame，失败时返回空DataFrame
    """
    if df.empty:
        logger.warning("输入数据为空")
        return pd.DataFrame()
    
    # 1. 检查必要列
    missing_columns = [col for col in REQUIRED_COLUMNS if col not in df.columns]
    if missing_columns:
        logger.error(f"数据缺失关键列: {missing_columns}")
        return pd.DataFrame()
    
    # 2. 检查时间戳
    if 'timestamp' not in df.columns:
        logger.error("数据缺少时间戳列")
        return pd.DataFrame()
    
    # 3. 检查价格数据
    price_columns = ['open', 'high', 'low', 'close']
    for col in price_columns:
        if df[col].isnull().any():
            logger.warning(f"{col}列存在空值")
        if (df[col] <= 0).any():
            logger.warning(f"{col}列包含非正值")
    
    # 4. 检查时间序列顺序
    if not pd.api.types.is_datetime64_any_dtype(df['timestamp']):
        logger.warning("时间戳列不是日期时间格式，尝试转换...")
        try:
            df['timestamp'] = pd.to_datetime(df['timestamp'])
        except Exception as e:
            logger.error(f"时间戳转换失败: {e}")
            return pd.DataFrame()
    
    # 检查时间序列是否有序
    if not df['timestamp'].is_monotonic_increasing:
        logger.warning("时间序列未排序，将按时间排序")
        df = df.sort_values('timestamp')
    
    return df

def clean_stock_data(df):
    """
    清洗股票数据
    :param df: 输入的DataFrame
    :return: 清洗后的DataFrame
    """
    if df.empty:
        return df
    
    logger.info("开始数据清洗...")
    original_count = len(df)
    
    # 1. 处理缺失值
    df = handle_missing_values(df)
    
    # 2. 处理异常值
    df = handle_outliers(df)
    
    # 3. 处理重复值
    df = handle_duplicates(df)
    
    # 4. 验证价格逻辑
    df = validate_price_logic(df)
    
    logger.info(f"数据清洗完成，原始数据: {original_count} 条，清洗后: {len(df)} 条")
    return df

def handle_missing_values(df):
    """
    处理缺失值
    :param df: 输入的DataFrame
    :return: 处理后的DataFrame
    """
    # 处理时间戳缺失
    if df['timestamp'].isnull().any():
        logger.warning("时间戳存在缺失值，删除相关行")
        df = df.dropna(subset=['timestamp'])
    
    # 处理价格缺失
    price_cols = ['open', 'high', 'low', 'close']
    for col in price_cols:
        if df[col].isnull().any():
            if MISSING_DATA_HANDLING == 'drop':
                logger.warning(f"{col}列存在缺失值，删除相关行")
                df = df.dropna(subset=[col])
            else:  # fill
                # 使用前一根K线的收盘价填充
                df[col].fillna(method='ffill', inplace=True)
                logger.info(f"{col}列缺失值已使用前向填充")
    
    # 处理成交量缺失
    if 'volume' in df.columns and df['volume'].isnull().any():
        df['volume'].fillna(0, inplace=True)
        logger.info("成交量缺失值已填充为0")
    
    return df

def handle_outliers(df):
    """
    处理异常值
    :param df: 输入的DataFrame
    :return: 处理后的DataFrame
    """
    # 计算价格变化百分比
    df['price_change'] = df['close'].pct_change() * 100
    
    # 识别异常波动
    abnormal = (df['price_change'].abs() > MAX_PRICE_CHANGE) & (df['price_change'].abs().shift(-1) < MAX_PRICE_CHANGE)
    
    if abnormal.any():
        logger.warning(f"发现 {abnormal.sum()} 个异常价格波动点")
        
        # 修正异常值：使用前后K线的平均值
        for idx in df.index[abnormal]:
            prev_close = df.at[idx-1, 'close'] if idx > 0 else df.at[idx+1, 'close']
            next_close = df.at[idx+1, 'close'] if idx < len(df)-1 else prev_close
            
            corrected_close = (prev_close + next_close) / 2
            logger.debug(f"修正异常值: 索引 {idx}, 时间 {df.at[idx, 'timestamp']}, "
                         f"原收盘价 {df.at[idx, 'close']}, 修正为 {corrected_close}")
            
            # 修正所有价格列
            ratio = corrected_close / df.at[idx, 'close']
            for col in ['open', 'high', 'low', 'close']:
                df.at[idx, col] *= ratio
    
    # 删除临时列
    if 'price_change' in df.columns:
        df.drop('price_change', axis=1, inplace=True)
    
    return df

def handle_duplicates(df):
    """
    处理重复值
    :param df: 输入的DataFrame
    :return: 处理后的DataFrame
    """
    # 检查时间戳重复
    duplicates = df['timestamp'].duplicated()
    if duplicates.any():
        logger.warning(f"发现 {duplicates.sum()} 个重复时间戳")
        
        # 保留最后出现的记录
        df = df.drop_duplicates(subset=['timestamp'], keep='last')
        logger.info("已删除重复的时间戳记录")
    
    return df

def validate_price_logic(df):
    """
    验证价格逻辑一致性
    :param df: 输入的DataFrame
    :return: 处理后的DataFrame
    """
    # 检查高价 >= 收盘价
    high_invalid = df['high'] < df['close']
    if high_invalid.any():
        logger.warning(f"发现 {high_invalid.sum()} 条高价 < 收盘价的记录")
        df.loc[high_invalid, 'high'] = df.loc[high_invalid, 'close']
    
    # 检查低价 <= 收盘价
    low_invalid = df['low'] > df['close']
    if low_invalid.any():
        logger.warning(f"发现 {low_invalid.sum()} 条低价 > 收盘价的记录")
        df.loc[low_invalid, 'low'] = df.loc[low_invalid, 'close']
    
    # 检查高价 >= 低价
    hl_invalid = df['high'] < df['low']
    if hl_invalid.any():
        logger.warning(f"发现 {hl_invalid.sum()} 条高价 < 低价的记录")
        # 交换高低价
        df.loc[hl_invalid, ['high', 'low']] = df.loc[hl_invalid, ['low', 'high']].values
    
    return df

def convert_timeframe(df, target_period):
    """
    转换K线周期
    :param df: 原始K线数据 (需包含timestamp, open, high, low, close, volume)
    :param target_period: 目标周期 ('60分钟', '日线', '周线', '月线')
    :return: 转换后的DataFrame
    """
    if df.empty:
        return df

    # 确保时间戳是日期时间类型
    if not pd.api.types.is_datetime64_any_dtype(df['timestamp']):
        df['timestamp'] = pd.to_datetime(df['timestamp'])

    # 设置时间戳为索引
    df = df.set_index('timestamp')

    # 定义聚合规则
    aggregation = {
        'open': 'first',
        'high': 'max',
        'low': 'min',
        'close': 'last',
        'volume': 'sum'
    }

    # 转换周期
    if target_period == '60分钟':
        resampled = df.resample('1H').agg(aggregation)
    elif target_period == '日线':
        resampled = df.resample('D').agg(aggregation)
    elif target_period == '周线':
        resampled = df.resample('W-MON').agg(aggregation)  # 周一作为周开始
    elif target_period == '月线':
        resampled = df.resample('M').agg(aggregation)  # 月末作为月结束
    else:
        logger.error(f"不支持的目标周期: {target_period}")
        return pd.DataFrame()

    # 重置索引并返回
    resampled = resampled.reset_index()
    resampled = resampled.dropna(subset=['open', 'high', 'low', 'close'])

    logger.info(f"K线周期转换完成: 原始数据 {len(df)} 条 -> 转换后 {len(resampled)} 条")
    return resampled

def detect_anomalies(df):
    """
    检测数据异常点
    :param df: 输入的DataFrame
    :return: 异常点报告
    """
    if df.empty:
        return "数据为空，无法检测异常"
    
    report = []
    
    # 1. 价格异常波动
    df['pct_change'] = df['close'].pct_change().abs() * 100
    big_moves = df[df['pct_change'] > MAX_PRICE_CHANGE]
    
    if not big_moves.empty:
        report.append(f"发现 {len(big_moves)} 个价格波动 > {MAX_PRICE_CHANGE}% 的异常点:")
        for _, row in big_moves.iterrows():
            report.append(f"  - {row['timestamp']}: {row['pct_change']:.2f}% 波动")
    
    # 2. 零成交量
    if 'volume' in df.columns:
        zero_volume = df[df['volume'] <= 0]
        if not zero_volume.empty:
            report.append(f"发现 {len(zero_volume)} 个零成交量K线")
    
    # 3. 高低价异常
    hl_ratio = (df['high'] - df['low']) / df['close']
    wide_range = df[hl_ratio > 0.1]  # 波动超过10%
    if not wide_range.empty:
        report.append(f"发现 {len(wide_range)} 个价格波动范围 > 10% 的K线")
    
    # 4. 收盘价等于最高/最低价
    close_high = df[df['close'] == df['high']]
    close_low = df[df['close'] == df['low']]
    if not close_high.empty:
        report.append(f"发现 {len(close_high)} 个收盘价等于最高价的K线")
    if not close_low.empty:
        report.append(f"发现 {len(close_low)} 个收盘价等于最低价的K线")
    
    # 5. 时间间隔异常
    if len(df) > 1:
        time_diffs = df['timestamp'].diff().dt.total_seconds()
        irregular_intervals = time_diffs[time_diffs > time_diffs.mode().iloc[0] * 1.5]
        if not irregular_intervals.empty:
            report.append(f"发现 {len(irregular_intervals)} 个时间间隔异常的K线")
    
    if not report:
        return "未检测到明显异常点"
    
    return "\n".join(report)

def add_technical_features(df):
    """
    添加额外的技术特征
    :param df: 包含基础K线数据的DataFrame
    :return: 添加特征后的DataFrame
    """
    if df.empty:
        return df
    
    # 添加价格变化特征
    df['price_change'] = df['close'].pct_change()
    df['high_change'] = df['high'].pct_change()
    df['low_change'] = df['low'].pct_change()
    
    # 添加波动率特征
    df['range'] = df['high'] - df['low']
    df['range_pct'] = df['range'] / df['close'].shift(1)
    
    # 添加相对位置特征
    df['close_position'] = (df['close'] - df['low']) / (df['high'] - df['low'])
    
    # 添加成交量特征
    if 'volume' in df.columns:
        df['volume_change'] = df['volume'].pct_change()
        df['volume_ma5'] = df['volume'].rolling(5).mean()
        df['volume_ratio'] = df['volume'] / df['volume_ma5']
    
    # 添加时间特征
    df['day_of_week'] = df['timestamp'].dt.dayofweek
    df['month'] = df['timestamp'].dt.month
    df['year'] = df['timestamp'].dt.year
    
    return df

def format_for_deepseek(df, symbol, period):
    """
    格式化数据用于DeepSeek分析
    :param df: 包含数据的DataFrame
    :param symbol: 股票代码
    :param period: K线周期
    :return: 格式化后的字符串
    """
    if df.empty:
        return "无有效数据"
    
    # 获取关键统计信息
    start_date = df['timestamp'].min().strftime('%Y-%m-%d')
    end_date = df['timestamp'].max().strftime('%Y-%m-%d')
    num_bars = len(df)
    
    # 创建数据摘要
    summary = f"# {symbol} {period} K线数据分析\n\n"
    summary += f"**数据范围**: {start_date} 至 {end_date} ({num_bars} 根K线)\n\n"
    
    # 添加关键指标
    summary += "## 关键统计指标\n"
    summary += f"- 平均收盘价: {df['close'].mean():.2f}\n"
    summary += f"- 最高价: {df['high'].max():.2f}\n"
    summary += f"- 最低价: {df['low'].min():.2f}\n"
    if 'volume' in df.columns:
        summary += f"- 平均成交量: {df['volume'].mean():,.0f}\n"
    
    # 添加技术指标（如果存在）
    tech_cols = [col for col in df.columns if col not in ['timestamp', 'open', 'high', 'low', 'close', 'volume']]
    if tech_cols:
        summary += "\n## 技术指标摘要\n"
        for col in tech_cols[:5]:  # 只显示前5个技术指标
            if pd.api.types.is_numeric_dtype(df[col]):
                summary += f"- {col}: 均值={df[col].mean():.2f}, 最新值={df[col].iloc[-1]:.2f}\n"
    
    # 添加最新K线数据
    latest = df.iloc[-1]
    summary += "\n## 最新K线数据\n"
    summary += f"- 时间: {latest['timestamp']}\n"
    summary += f"- 开盘: {latest['open']:.2f}\n"
    summary += f"- 最高: {latest['high']:.2f}\n"
    summary += f"- 最低: {latest['low']:.2f}\n"
    summary += f"- 收盘: {latest['close']:.2f}\n"
    if 'volume' in df.columns:
        summary += f"- 成交量: {latest['volume']:,.0f}\n"
    
    # 添加分析建议
    summary += "\n## 分析建议\n"
    summary += "请基于以上数据：\n"
    summary += "1. 识别关键支撑位和阻力位\n"
    summary += "2. 分析当前趋势方向\n"
    summary += "3. 评估多空信号有效性\n"
    summary += "4. 预测短期价格走势\n"
    summary += "5. 给出具体交易建议\n"
    
    return summary

def optimize_analysis_data(df, optimization_level='balanced'):
    """
    优化精简analysis.csv数据
    :param df: 完整的分析数据DataFrame
    :param optimization_level: 优化级别 ('minimal', 'balanced', 'comprehensive')
    :return: 优化后的DataFrame
    """
    if df.empty:
        logger.warning("输入数据为空，无法优化")
        return df

    logger.info(f"开始数据优化，优化级别: {optimization_level}")
    logger.info(f"原始数据: {len(df)} 行 × {len(df.columns)} 列")

    # 定义不同优化级别的核心列
    core_columns = {
        'minimal': [
            # 基础OHLCV数据
            '时间', '开盘价', '最高价', '最低价', '收盘价', '成交量',
            # 核心技术指标
            '20日均线', 'RSI相对强弱指数', 'MACD快慢线差值',
            # 关键信号
            '交易建议', '风险等级', '趋势强度'
        ],

        'balanced': [
            # 基础OHLCV数据
            '时间', '开盘价', '最高价', '最低价', '收盘价', '成交量', '股票代码',
            # 移动平均线
            '5日均线', '10日均线', '20日均线', '60日均线',
            # 核心技术指标
            'RSI相对强弱指数', 'RSI超买信号', 'RSI超卖信号',
            'MACD快慢线差值', 'MACD信号线', 'MACD柱状图', 'MACD金叉死叉',
            '布林带上轨', '布林带中轨', '布林带下轨', '价格布林带位置',
            'KDJ_K值', 'KDJ_D值', 'KDJ_J值', 'KDJ金叉', 'KDJ死叉',
            # 波动率指标
            '真实波动幅度', 'ATR百分比', '20日历史波动率',
            # 成交量指标
            '成交量加权均价', 'VWAP偏离度', '能量潮指标',
            # 交易信号
            '多头信号', '空头信号', '多头强度', '空头强度',
            '多头止损位', '空头止损位', '建议仓位大小',
            # 综合评估
            '风险评分', '风险等级', '趋势评分', '动量评分', '综合评分',
            '交易建议', '趋势强度'
        ],

        'comprehensive': [
            # 保留大部分重要指标，但去除冗余和不常用的
            '时间', '开盘价', '最高价', '最低价', '收盘价', '成交量', '股票代码',
            # 移动平均线
            '5日均线', '10日均线', '20日均线', '60日均线',
            # RSI系列
            'RSI相对强弱指数', 'RSI超买信号', 'RSI超卖信号',
            # MACD系列
            'MACD快慢线差值', 'MACD信号线', 'MACD柱状图', 'MACD金叉死叉',
            # 布林带系列
            '布林带上轨', '布林带中轨', '布林带下轨', '布林带宽度', '价格布林带位置', '布林带突破',
            # KDJ系列
            'KDJ_K值', 'KDJ_D值', 'KDJ_J值', 'KDJ金叉', 'KDJ死叉',
            # 高级技术指标
            '真实波动幅度', 'ATR百分比', '平均趋向指数',
            '商品通道指数', 'CCI超买', 'CCI超卖',
            '威廉指标', '威廉超买', '威廉超卖',
            # 市场情绪
            '恐慌贪婪指数', '市场情绪', '市场强度',
            # 成交量分析
            '成交量加权均价', 'VWAP偏离度', '能量潮指标', 'OBV信号',
            '资金流量指数', 'MFI超买', 'MFI超卖',
            # 波动率分析
            '5日历史波动率', '20日历史波动率', '60日历史波动率',
            '波动率分位数', '波动率突破',
            # 交易信号
            '基础多头信号', '基础空头信号', '多头强度', '空头强度',
            '多头信号', '空头信号', '突破多头', '突破空头',
            '顶背离', '底背离', '锤子线', '上吊线',
            # 风险管理
            '多头止损位', '空头止损位', '建议仓位大小',
            '风险评分', '风险等级', '最大仓位',
            # 综合评估
            '趋势评分', '动量评分', '综合评分', '交易建议', '趋势强度'
        ],

        'custom_essential': [
            # 用户自定义的精简核心列表 (30列)
            '时间', '开盘价', '最高价', '最低价', '收盘价', '成交量',
            '5日指数均线', 'RSI相对强弱指数', 'MACD快慢线差值', 'MACD信号线',
            '布林带上轨', '布林带中轨', '布林带下轨', 'KDJ_K值', 'KDJ_D值',
            '真实波动幅度', '商品通道指数', '威廉指标', '随机RSI_K', '变动率指标',
            '动量指标', '恐慌贪婪指数', '市场情绪', '市场强度', '价格位置百分比',
            '能量潮指标', '成交量加权均价', 'VWAP偏离度', '资金流量指数', '20日历史波动率'
        ]
    }

    # 获取目标列
    target_columns = core_columns.get(optimization_level, core_columns['balanced'])

    # 过滤存在的列
    available_columns = [col for col in target_columns if col in df.columns]
    missing_columns = [col for col in target_columns if col not in df.columns]

    if missing_columns:
        logger.warning(f"以下列在数据中不存在: {missing_columns}")

    # 创建优化后的数据
    optimized_df = df[available_columns].copy()

    # 数据质量优化
    optimized_df = _optimize_data_quality(optimized_df)

    logger.info(f"优化完成: {len(optimized_df)} 行 × {len(optimized_df.columns)} 列")
    logger.info(f"数据压缩率: {(1 - len(optimized_df.columns) / len(df.columns)) * 100:.1f}%")

    return optimized_df

def _optimize_data_quality(df):
    """
    优化数据质量
    :param df: 输入DataFrame
    :return: 质量优化后的DataFrame
    """
    # 1. 处理数值精度
    numeric_columns = df.select_dtypes(include=[np.number]).columns
    for col in numeric_columns:
        if col not in ['时间', '成交量']:  # 保持成交量和时间的原始精度
            # 价格相关保留2位小数
            if any(keyword in col for keyword in ['价', '均线', 'MACD', '布林带', '止损', 'VWAP']):
                df[col] = df[col].round(2)
            # 百分比和比率保留4位小数
            elif any(keyword in col for keyword in ['率', '百分比', 'RSI', 'KDJ', '波动', '评分']):
                df[col] = df[col].round(4)
            # 其他指标保留3位小数
            else:
                df[col] = df[col].round(3)

    # 2. 优化布尔值列
    boolean_columns = ['RSI超买信号', 'RSI超卖信号', 'MACD金叉死叉', 'KDJ金叉', 'KDJ死叉',
                      'CCI超买', 'CCI超卖', '威廉超买', '威廉超卖', 'MFI超买', 'MFI超卖',
                      '基础多头信号', '基础空头信号', '多头信号', '空头信号',
                      '突破多头', '突破空头', '顶背离', '底背离', '锤子线', '上吊线',
                      'OBV信号', '布林带突破', '波动率突破']

    for col in boolean_columns:
        if col in df.columns:
            # 将布尔值转换为更简洁的表示
            df[col] = df[col].astype(int)  # True->1, False->0

    # 3. 优化分类列
    categorical_columns = ['风险等级', '交易建议', '市场情绪']
    for col in categorical_columns:
        if col in df.columns:
            # 转换为分类数据类型以节省内存
            df[col] = df[col].astype('category')

    return df

def create_analysis_summary(df, symbol, period):
    """
    创建分析数据摘要
    :param df: 分析数据DataFrame
    :param symbol: 股票/期货代码
    :param period: 周期
    :return: 摘要字典
    """
    if df.empty:
        return {}

    summary = {
        'basic_info': {
            'symbol': symbol,
            'period': period,
            'data_points': len(df),
            'date_range': {
                'start': df['时间'].min() if '时间' in df.columns else None,
                'end': df['时间'].max() if '时间' in df.columns else None
            }
        },
        'price_summary': {},
        'technical_summary': {},
        'signal_summary': {},
        'risk_summary': {}
    }

    # 价格摘要
    if '收盘价' in df.columns:
        summary['price_summary'] = {
            'latest_price': float(df['收盘价'].iloc[-1]),
            'highest_price': float(df['最高价'].max()) if '最高价' in df.columns else None,
            'lowest_price': float(df['最低价'].min()) if '最低价' in df.columns else None,
            'average_price': float(df['收盘价'].mean()),
            'price_change_pct': float((df['收盘价'].iloc[-1] / df['收盘价'].iloc[0] - 1) * 100) if len(df) > 1 else 0
        }

    # 技术指标摘要
    if 'RSI相对强弱指数' in df.columns:
        summary['technical_summary']['rsi'] = float(df['RSI相对强弱指数'].iloc[-1])
    if 'MACD快慢线差值' in df.columns:
        summary['technical_summary']['macd'] = float(df['MACD快慢线差值'].iloc[-1])
    if '20日均线' in df.columns:
        summary['technical_summary']['ma20'] = float(df['20日均线'].iloc[-1])

    # 信号摘要
    signal_columns = ['多头信号', '空头信号', '基础多头信号', '基础空头信号']
    for col in signal_columns:
        if col in df.columns:
            summary['signal_summary'][col] = int(df[col].sum())

    # 风险摘要
    if '风险等级' in df.columns:
        summary['risk_summary']['risk_level'] = df['风险等级'].iloc[-1]
    if '交易建议' in df.columns:
        summary['risk_summary']['recommendation'] = df['交易建议'].iloc[-1]
    if '综合评分' in df.columns:
        summary['risk_summary']['overall_score'] = float(df['综合评分'].iloc[-1])

    return summary

def export_optimized_analysis(df, symbol, period, optimization_level='balanced', output_dir='.'):
    """
    导出优化后的分析数据
    :param df: 完整分析数据
    :param symbol: 股票/期货代码
    :param period: 周期
    :param optimization_level: 优化级别
    :param output_dir: 输出目录
    :return: 导出文件路径
    """
    # 优化数据
    optimized_df = optimize_analysis_data(df, optimization_level)

    # 生成文件名
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    filename = f"{symbol}_{period}_{timestamp}_optimized_{optimization_level}.csv"
    filepath = f"{output_dir}/{filename}"

    # 导出CSV
    optimized_df.to_csv(filepath, index=False, encoding='utf-8-sig')

    # 创建摘要
    summary = create_analysis_summary(optimized_df, symbol, period)

    # 导出摘要JSON
    import json
    summary_filename = f"{symbol}_{period}_{timestamp}_summary.json"
    summary_filepath = f"{output_dir}/{summary_filename}"

    with open(summary_filepath, 'w', encoding='utf-8') as f:
        json.dump(summary, f, ensure_ascii=False, indent=2, default=str)

    # 记录导出信息
    original_size = len(df.columns) * len(df)
    optimized_size = len(optimized_df.columns) * len(optimized_df)
    compression_ratio = (1 - optimized_size / original_size) * 100

    logger.info(f"数据导出完成:")
    logger.info(f"  优化数据: {filepath}")
    logger.info(f"  数据摘要: {summary_filepath}")
    logger.info(f"  压缩比例: {compression_ratio:.1f}%")
    logger.info(f"  数据规模: {len(optimized_df)} 行 × {len(optimized_df.columns)} 列")

    return filepath, summary_filepath

def auto_optimize_analysis_file(analysis_filepath, optimization_level='balanced'):
    """
    自动优化分析文件
    :param analysis_filepath: 分析文件路径
    :param optimization_level: 优化级别
    :return: 优化文件路径
    """
    try:
        # 读取分析文件
        df = pd.read_csv(analysis_filepath)

        # 从文件名提取信息
        filename = os.path.basename(analysis_filepath)
        parts = filename.replace('_analysis.csv', '').split('_')

        if len(parts) >= 2:
            symbol = parts[0]
            period = parts[1]
        else:
            symbol = 'UNKNOWN'
            period = '日线'

        # 执行优化
        output_dir = os.path.dirname(analysis_filepath) or '.'
        optimized_filepath, summary_filepath = export_optimized_analysis(
            df, symbol, period, optimization_level, output_dir
        )

        logger.info(f"✅ 自动优化完成: {optimized_filepath}")
        return optimized_filepath

    except Exception as e:
        logger.error(f"❌ 自动优化失败 {analysis_filepath}: {e}")
        return None

def get_optimization_recommendation(df):
    """
    根据数据特征推荐最佳优化策略
    :param df: 分析数据DataFrame
    :return: 推荐的优化级别和原因
    """
    if df.empty:
        return 'balanced', '数据为空，使用默认策略'

    column_count = len(df.columns)
    row_count = len(df)
    data_size = column_count * row_count

    # 检查是否包含交易信号
    has_trading_signals = any('信号' in col or '强度' in col for col in df.columns)

    # 检查是否包含风险管理指标
    has_risk_management = any('风险' in col or '止损' in col or '仓位' in col for col in df.columns)

    # 检查是否包含成交量指标
    has_volume_analysis = any('VWAP' in col or 'OBV' in col or 'MFI' in col for col in df.columns)

    # 推荐逻辑
    if data_size > 20000:  # 大数据集
        if has_trading_signals and has_risk_management:
            return 'trading_focused', '大数据集且包含完整交易信号，推荐交易导向策略'
        else:
            return 'minimal', '大数据集，推荐最小化策略以获得最高压缩率'

    elif data_size > 10000:  # 中等数据集
        if has_volume_analysis:
            return 'volume_analysis', '中等数据集且包含成交量分析，推荐成交量分析策略'
        elif has_risk_management:
            return 'risk_management', '中等数据集且包含风险管理，推荐风险管理策略'
        else:
            return 'balanced', '中等数据集，推荐平衡化策略'

    else:  # 小数据集
        if column_count > 80:
            return 'comprehensive', '小数据集但列数较多，推荐全面化策略保留更多信息'
        else:
            return 'balanced', '小数据集，推荐平衡化策略'

# 测试函数
def test_utils_functions():
    """测试工具函数"""
    print("=" * 50)
    print("工具函数模块测试")
    print("=" * 50)
    
    # 创建测试数据
    dates = pd.date_range(start='2023-01-01', periods=100, freq='D')
    prices = np.cumsum(np.random.randn(100)) + 100
    
    # 故意添加一些异常数据
    test_data = pd.DataFrame({
        'timestamp': dates,
        'open': prices - np.random.rand(100) * 2,
        'high': prices + np.random.rand(100) * 2,
        'low': prices - np.random.rand(100) * 3,
        'close': prices,
        'volume': np.random.randint(10000, 50000, 100)
    })
    
    # 添加异常点
    test_data.loc[10, 'close'] = 200  # 价格突变
    test_data.loc[20, 'volume'] = 0   # 零成交量
    test_data.loc[30, 'high'] = test_data.loc[30, 'low'] - 1  # 高价低于低价
    test_data.loc[40, 'close'] = test_data.loc[40, 'high'] + 1  # 收盘价高于最高价
    test_data = test_data.append(test_data.iloc[50])  # 添加重复数据
    
    print("原始数据:")
    print(test_data.head(3))
    
    # 测试数据验证
    print("\n测试数据验证...")
    validated = validate_stock_data(test_data)
    print(f"验证后数据量: {len(validated)}")
    
    # 测试数据清洗
    print("\n测试数据清洗...")
    cleaned = clean_stock_data(validated)
    print(f"清洗后数据量: {len(cleaned)}")
    
    # 测试异常检测
    print("\n测试异常检测...")
    anomalies = detect_anomalies(cleaned)
    print("异常检测报告:")
    print(anomalies)
    
    # 测试周期转换
    print("\n测试周期转换 (日线转周线)...")
    weekly = convert_timeframe(cleaned, '周线')
    print(f"转换后周线数据量: {len(weekly)}")
    print(weekly.head(2))

    # 测试格式化输出
    print("\n测试DeepSeek格式化...")
    deepseek_format = format_for_deepseek(weekly, 'AAPL', '周线')
    print(deepseek_format[:500] + "...")  # 只显示部分内容
    
    print("\n工具函数测试完成")

if __name__ == "__main__":
    test_utils_functions()